
package com.smfx.yxt.excel.tags;

import java.util.StringTokenizer;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.ss.util.CellRangeAddress;

import com.smfx.yxt.excel.ExcelParser;
import com.smfx.yxt.excel.ExcelUtils;
import com.smfx.yxt.excel.WorkbookUtils;

/**
 * <b>RepeatTag</b> is a class which parse #repeat #end <BR>
 * #repeat .. with ..
 * 
 */
public class RepeatTag implements ITag {
	public static final String KEY_REPEAT = "#repeat";

	public static final String KEY_END = "#end";

	public int[] parseTag(HSSFSheet sheet, HSSFRow curRow, HSSFCell curCell) {
		int repeatstart = curRow.getRowNum();
		int repeatend = -1;
		int repeatCount = 0;
		String repeatstr = "";
		boolean bFind = false;
		for (int rownum = repeatstart; rownum <= sheet.getLastRowNum(); rownum++) {
			HSSFRow row = sheet.getRow(rownum);
			if (null == row)
				continue;
			for (int colnum = row.getFirstCellNum(); colnum <= row.getLastCellNum(); colnum++) {
				HSSFCell cell = row.getCell(colnum);
				if (null == cell)
					continue;
				if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
					String cellstr = cell.getRichStringCellValue().getString();

					// get the tag instance for the cellstr
					ITag tag = ExcelParser.getTagClass(cellstr);

					if (null != tag) {
						if (tag.hasEndTag()) {
							if (0 == repeatCount) {
								repeatstart = rownum;
								repeatstr = cellstr;
							}
							repeatCount++;
							break;
						}
					}
					if (cellstr.startsWith(KEY_END)) {
						repeatend = rownum;
						repeatCount--;
						if (repeatstart >= 0 && repeatend >= 0 && repeatend > repeatstart && repeatCount == 0) {
							bFind = true;
						}
						break;
					}
				}
			}
			if (bFind)
				break;
		}

		if (!bFind)
			return new int[] { 0, 0, 1 };

		// test if condition
		int iResult = 0;
		// remove #if tag and get condition expression
		String repeat = repeatstr.trim().substring(KEY_REPEAT.length()).trim();

		String expr = null;
		String indexVariable = null;

		StringTokenizer st = new StringTokenizer(repeat, " ");
		int pos = 0;
		while (st.hasMoreTokens()) {
			String str = st.nextToken();
			if (pos == 0) {
				expr = str;
			}
			if (pos == 2) {
				indexVariable = str;
			}
			pos++;
		}

		Object v = null;
		// parse the condition expression
		try {
			v = ExcelParser.parseExpr(expr);
			if (v instanceof Number) {
				iResult = ((Number) ExcelParser.parseExpr(expr)).intValue();
			}
			else {
				if (!(v instanceof String)) {
					v = v.toString();
				}
				iResult = Integer.parseInt((String) v);
			}
		}
		catch (Exception e) {//
		}

		// iterator
		int shiftNum = repeatend - repeatstart - 1;

		int old_repeatend = repeatend;
		int shift = 0;
		if (iResult > 0) {
			for (int i = 0; i < iResult; i++) {
				ExcelUtils.addValue(indexVariable, i + 1);

				// shift the #foreach #end block
				sheet.shiftRows(repeatstart, sheet.getLastRowNum(), shiftNum, true, true);
				// copy the body fo #foreach #end block
				WorkbookUtils.copyRow(sheet, repeatstart + shiftNum + 1, repeatstart, shiftNum);
				// parse
				shift = ExcelParser.parse(sheet, repeatstart, repeatstart + shiftNum - 1);
				repeatstart += shiftNum + shift;
				repeatend += shiftNum + shift;
			}
		}
		// delete #foreach #end block
		for (int rownum = repeatstart; rownum <= repeatend; rownum++) {
			sheet.removeRow(WorkbookUtils.getRow(rownum, sheet));
		}

		// remove merged region in repeatstart & repeatend
		for (int i = 0; i < sheet.getNumMergedRegions(); i++) {
			CellRangeAddress r = sheet.getMergedRegion(i);
			if (r.getFirstRow() >= repeatstart && r.getLastRow() <= repeatend) {
				sheet.removeMergedRegion(i);
				// we have to back up now since we removed one
				i = i - 1;
			}
		}

		sheet.shiftRows(repeatend + 1, sheet.getLastRowNum(), -(repeatend - repeatstart + 1), true, true);

		return new int[] { ExcelParser.getSkipNum(repeatstart, repeatend),
				ExcelParser.getShiftNum(old_repeatend, repeatstart), 1 };
	}

	public String getTagName() {
		return KEY_REPEAT;
	}

	public boolean hasEndTag() {
		return true;
	}
}
